package com.qudian.pay.core.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description: 序列化/反序列化工具类
 * @ClassName: JdkSerializer
*
 * @date 2016年5月17日 下午5:52:00
 */ 
public class JdkSerializer {
	
	private final static Logger logger = LoggerFactory.getLogger(JdkSerializer.class);
	
	public static byte[] serialize(Object obj) throws IOException {
		ByteArrayOutputStream bis = null;
		ObjectOutputStream os = null;
		byte[] byteArray = (byte[]) null;
		try {
			bis = new ByteArrayOutputStream();
			os = new ObjectOutputStream(bis);
			os.writeObject(obj);
			os.flush();
			byteArray = bis.toByteArray();
		} catch (IOException e) {
			logger.error("Object convert to bytes array fail", e);
			throw e;
		} finally {
			closeOutputStream(os, bis);
		}
		return byteArray;
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T deSerialize(byte[] byteArray) throws IOException, ClassNotFoundException {
		ByteArrayInputStream bos = null;
		ObjectInputStream ois = null;
		Object obj = null;
		try {
			bos = new ByteArrayInputStream(byteArray);
			ois = new ObjectInputStream(bos);
			obj = ois.readObject();
		} catch (IOException e) {
			logger.error("bytes array convert to object fail", e);
			throw e;
		} catch (ClassNotFoundException e) {
			logger.error("bytes array convert to object fail", e);
			throw e;
		} finally {
			closeInputStream(bos, ois);
		}
		return (T) obj;
	}
	
	private static void closeOutputStream(ObjectOutputStream os, ByteArrayOutputStream bis) throws IOException {
		if (os != null) {
			try {
				os.close();
			} catch (IOException e) {
				logger.error("close objectOutputStream fail", e);
				throw e;
			}
		}
		if (bis != null) {
			try {
				bis.close();
			} catch (IOException e) {
				logger.error("close byteArrayOutputStream fail", e);
				throw e;
			}
		}
	}
	
	private static void closeInputStream(ByteArrayInputStream bos, ObjectInputStream ois) throws IOException {
		if (bos != null) {
			try {
				bos.close();
			} catch (IOException e) {
				logger.error("close objectInputStream fail", e);
				throw e;
			}
		}
		if (ois != null) {
			try {
				ois.close();
			} catch (IOException e) {
				logger.error("close byteArrayInputStream fail", e);
				throw e;
			}
		}
	}
}
